/*   This file is part of lanSimulation.
 *
 *   lanSimulation is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   lanSimulation is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with lanSimulation; if not, write to the Free Software
 *   Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *   Copyright original Java version: 2004 Bart Du Bois, Serge Demeyer
 *   Copyright C++ version: 2006 Matthias Rieger, Bart Van Rompaey
 */
package lanSimulation.internals;

import java.io.IOException;
import lanSimulation.LogManager;

/**
 * A <em>Node</em> represents a single Node in a Local Area Network (LAN).
 * Several types of Nodes exist.
 */
public class Node {
	

	/**
	 * Holds the name of the Node.
	 */
	public String name_;

	/**
	 * Holds the next Node in the token ring architecture.
	 * 
	 * @see lanSimulation.internals.Node
	 */
	public Node nextNode_;

        protected LogManager logManager;

	/**
	 * Construct a <em>Node</em> with given #type and #name.
	 * <p>
	 * <strong>Precondition:</strong> (type >= NODE) & (type <= PRINTER);
	 * </p>
	 */
	public Node( String name, LogManager logman) {
		name_ = name;
		nextNode_ = null;
                logManager = logman;
	}

	/**
	 * Construct a <em>Node</em> with given #type and #name, and which is
	 * linked to #nextNode.
	 * <p>
	 * <strong>Precondition:</strong> (type >= NODE) & (type <= PRINTER);
	 * </p>
	 */
	public Node(String name, Node nextNode, LogManager logman) {
		
		name_ = name;
		nextNode_ = nextNode;
                logManager = logman;
	}

        public LogManager getLogManager(){
            return logManager;
        }

        public boolean equals(String name){
            return this.name_.equals(name);
        }

        public boolean equalsType(Class type){
            return type.equals(Node.class);
        }

        public void receivePacket(Packet packet){
            logManager.log("\tNode '");
            logManager.log(this.name_);
            logManager.log("' accepts broadcase packet.\n");
        }

        public void sendPacket(Packet packet){
            logManager.log("\tNode '");
            logManager.log(this.name_);
            logManager.log("' passes packet on.\n");
        }

        public void broadcastPacket(Packet packet){

            if(!this.name_.equals(packet.destination_)){

                receivePacket(packet);
                sendPacket(packet);
                logManager.flush();
                
                this.nextNode_.broadcastPacket(packet);

            }

        }

        public boolean transmitPrintPacket(Packet packet){

            boolean result = false;

            if ((!packet.isDestinationReached(this))
				&& (!packet.isOriginReached(this))){

                sendPacket(packet);
                return this.nextNode_.transmitPrintPacket(packet);

            }

            if (packet.isDestinationReached(this)) {
			result = printDocument(this, packet);
            }

            if (packet.isOriginReached(this)) {
                    logManager.log(">>> Destinition not found, print job cancelled.\n\n");
            }

            return result;
        }


        protected boolean printDocument(Node node, Packet document) {

                logManager.log(">>> Destinition is not a printer, print job cancelled.\n\n");
                logManager.flush();
		
		return false;
                
	}

        public void printOn(StringBuffer buf){
            
            buf.append("Node ");
            buf.append(this.name_);
            buf.append(" [Node]");
        
        }

        public void printXmlOn(StringBuffer buf){
            
            buf.append("<node>");
            buf.append(this.name_);
            buf.append("</node>");
	
        }
}